home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-08-29 | 6.1 KB | 126 lines | [TEXT/KAHL] |
-
- Here is how the SCC hardware and interrupt routines receive AppleTalk
- packets. See figure 4 in "Inside Macintosh", pages III-26, to see how
- the signals from AppleTalk get to SCC (they come in on RXD- and RXD+ from
- the little box hanging out back).
-
- The SCC (Zilog 8530) serial communications controller receives the bits and
- assembles them into bytes. If you are going to be programming the SCC, you
- will need to get a copy of the Z8530 section of a Zilog data book, which will
- explain (to some extent) what the zillions of registers are for.
-
- Macintosh to SCC I/O Interface:
-
- The SCC has two registers presented to the bus for each channel (A and B).
- Each register can be read and written to. For writing to the SCC
- use the address in system global SCCWr + (aData(6), bData(4), aCtl(2),
- bCtl(0)) depending on which register you want. For reading to the SCC, use
- SCCRd, which is accessed the same way.
-
- To read or write to the SCC, you generally do a write to the control port
- to tell it which internal register you want. Then you do a read or a write
- to the control port again to get/send the data you want Be sure to have at
- least one instruction delay between accesses (one NOP instruction is fine)
- to meet the SCC timing requirments.
-
- Macintosh to SCC Interrupts:
-
- There are two channels, SCC B and SCC A, which are basically independent in
- the operation and seperation of their registers and wiring. The only
- exceptions are RR2 and RR3 (read registers 2 and 3). RR3 is the interrupt
- pending status register and can only be read from channel B. RR2 is
- the interrupt vector register (SCC interrupts do not vector according to
- this hardware vector, they vector according to 68000 interrupt level only -
- more on this later). If you read RR2 from the B side it always
- returns the interrupt vector that the SCC was initilized with (which should
- always be set to zero or the ROM interrupt handler will be confused).
- However, when you read from side A the interrupt vector is modified by the
- 8 different possible pending interrupts (according to the highest SCC
- priority).
-
-
- When the SCC requests an interrupt from the 68K, the 68K pushes the SR
- (status /CCR register) and PC onto the stack. Since the SCC is on level
- 2 (see "Inside Macintosh", pages III-197 fig 4) the 68K loads the contents
- of the long word at $68 into the program counter. On my Macintosh Plus,
- $68 points to $401A84, which does the following:
- save D0-D3/A0-A3; /* preserve the users registers */
- A0 := SCCRd; /* setup SCC read/write addresses */
- A1 := SCCWr;
- D0 := *SCCRd & 0xe0; /* see who is interrupting within the SCC */
- if(D0>=8) { /* channel A? */
- A0 +=2; /* yes, change SCC addresses to point to */
- A1 +=2; /* SCC A registers instead of B registers */
- } /* else A0/A1 point to B */
- A2 := Lvl2DT[D0]; /* select service routine */
- JSR (A2) /* call the service routine */
- restore D0-D3/A0-A3; /* put the users register back */
- RTE /* return from interrupt */
-
- Put your own transmit buffer empty, receive special condition, and
- receive character interrupt handlers into Lvl2DT. Do *NOT* change
- the external status entry in Lvl2DT because the mouse vertical and
- horizotal position sensors are connected to a general purpose input to the
- SCC. If the mouse moves vertically you get SCC B external interrupts. So
- do not change the external interrupt in Lvl2DT, as it checks to see if the
- interrupt is due to the mouse or communications, and vectors thru ExtStsDT.
-
- Again on my Macintosh Plus, Lvl2DT+4 (SCC B external) points to this routine
- in the ROM:
-
- channel_B_external_interrupt:
- D0 :=SCCRd+bCtl; /* get SCC status */
- A2 :=ExtStsDt; /* point to the B side of ExtStsDt */
- A3 := &SCCBSts; /* point to SCC status byte in low memory */
- goto common_external_interrupt
-
- channel_A_external_interrupt:
- D0 :=SCCRd+aCtl; /* get SCC status */
- A2 :=ExtStsDt+8; /* point to the A side of ExtStsDt */
- A3 := &SCCASts; /* point to SCC status byte in low memory */
-
- common_external_interrupt:
- /* here we set D1 to be those status bits in RR0 (abort, tx undeflow,
- CTS (clear to send), sync/hunt, DCD (mouse), Tx empty, zero in baud
- generator, Rx available, anded with those channels that are enabled.
-
- In other words, D1 is those RR0 conditions that are different that
- we are interested in.
- */
- D1 := ( *SCCxSts Xor RR0) && RR15;
- /* save current state so next interrupt can know what is different */
- *SCCxSts := D0;
- /* is the *ONLY* new status change due to the mouse? */
- if( D1 = 8) /* check DCD SCC input */
- A2 +=2; /* yes,just the mouse, select mouse interrupt routine */
- /* *************** very important ************** */
- /* tell the SCC that the current interrupt had been serviced, (end IUS
- interrupt under service. NOTE: for all the other routines you
- might write interrupt handlers for (data interrupt, trasmit, special)
- they must do a IUS to the SCC. For the external interrupt, the
- user routine does not, as it is done right here.
- */
- WW0 := $10; /* end interrupt under service */
- /* go to user external service routine.
- registers:
- D0 - SCC status
- D1 - SCC status that is different since the last interrupt
- D2 - trash
- D3 - trash
- A0 - SCC read address
- A1 - SCC write address
- A2 - trash
- A3 - trash
- You must preserve all the other regs. D0-D3/A0-A3 may be trashed.
- N.B. SCC communication conditions have priority over mouse, so if
- there is a communications status change at the same time the mouse moves
- then this JMP (A2) only calls the communication routine. Some
- communication routines have been seen to look at D1 and notice that
- there is a mouse interrupt also and jump to mouse routine when done
- servicing the communication interrupt. This is fine, but in that
- case preserve A0,A1, D0,D1 as the mouse routine needs them.
- */
- JMP (A2)
-
- *****************************************************************************
-